`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2018/06/18 14:09:38
// Design Name: 
// Module Name: v_ajxd
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module key(
    input               clk,
    input               rst_n,
    input       [3:0]   col,
    output  reg [3:0]   row,
    output      [4:0]   btn_clicked_num     //有效值1-16   无效值0
    );
    
    reg[15:0] btn=0;    
    reg[15:0] btn0=0;
    reg[15:0] btn1=0;
    reg[15:0] btn2=0;
    

    
    wire clk_dectect;
    divider #(
        .OUT_CLK(1000),
        .CLK(50000000)
    )
    btnClkCounter0(
        .clk (clk),
        .rst_n(rst_n),
        .out_clk(clk_dectect)
    );
    
    
    //行扫描---循环左移---输出
    always @ (posedge clk_dectect or negedge rst_n)begin
		if(rst_n == 1'b0)
            row[3:0] = 4'b0001;
        else if(row[3:0]==4'b1000)
            row[3:0]=4'b0001;
        else 
            row[3:0]=row[3:0]<<1; 
    end    


    //列扫描=== === ===在一个大周期（即四个clk）内，四个行输出条件下，
    //     === === ===采集列输入值（即16个按键哪个检测到行扫描）,高电平有效
    always @ (posedge clk_dectect)
    begin
        case (row[3:0])
        4'b0001:
            begin
                btn[3:0]=col;
            end
        4'b0010:
            begin
                btn[7:4]=col;
            end
        4'b0100:
            begin
                btn[11:8]=col;
            end
        4'b1000:
            begin
                btn[15:12]=col;
            end 
        default:btn=0;   		   
        endcase
    end  

    //消抖===(btn2&btn1&btn0)->三个btn_clk内都为有效状态
    //    ===(~btn2&btn1&btn0)->两个连续btn_clk内都为有效状态
    wire        [15:0]  btn_out;
    assign btn_out=(btn2&btn1&btn0)|(~btn2&btn1&btn0);
    

    //边沿检测===btn->btn0->btn1->btn2
    wire btn_clk;
    divider #(
            .OUT_CLK(50),
            .CLK(50000000)
        )
    btnClkCounter1(
            .clk (clk),
            .rst_n(rst_n),
            .out_clk(btn_clk)
    );
    
    always@ (posedge btn_clk)
    begin
        btn0<=btn;
        btn1<=btn0;
        btn2<=btn1;
    end
    
//将
wire         btn_valid;
wire  [15:0] btn_trigger;
trigger #(
    .reg_cnt(16)
)u_trigger_key(
    .clk(clk),	//系统时钟
    .rst_n(rst_n),
    .signal(btn_out),
    .signal_vld(btn_valid),
    .signal_trigger(btn_trigger)
);

reg [4:0] i;//因为i需要加到16一次
reg [4:0] btn_clicked_num_reg;//有效值1-16   无效值0
assign btn_clicked_num = btn_clicked_num_reg;
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) btn_clicked_num_reg = 0;
    else begin
        if(btn_trigger)begin
            for (i = 0; i <= 15; i = i + 1) begin
                if (btn_trigger[i] == 1) begin
                    btn_clicked_num_reg<=i+1;
                end
            end
        end
        else begin
            btn_clicked_num_reg<=0;
        end 
    end
end

endmodule
